﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace K9Nano.Share.Reflection
{
    public static class AssemblyHelper
    {
        public static IList<Type> GetClasses(this Assembly assembly, Func<TypeInfo, bool> predicate)
        {
            return assembly.DefinedTypes
                .Where(predicate)
                .Select(x => x.AsType())
                .ToList();
        }

        public static string GetFullName(this Type type)
        {
            var fullName = type.FullName;
            if (!string.IsNullOrEmpty(fullName)) return fullName;

            var innerType = type;
            while (true)
            {
                if (!string.IsNullOrEmpty(innerType.FullName))
                {
                    fullName += "." + innerType.FullName;
                    return fullName;
                }
                if (innerType.IsGenericType && innerType.GenericTypeArguments.Length == 1)
                {
                    innerType = innerType.GenericTypeArguments[0];
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
        }

        public static object GetProperty(this object obj, string propertyName)
        {
            var property = obj.GetType().GetProperty(propertyName);
            if (property == null) return null;
            return property.GetValue(obj);
        }

        public static object GetField(this object obj, string fieldName)
        {
            var property = obj.GetType().GetField(fieldName);
            if (property == null) return null;
            return property.GetValue(obj);
        }
    }
}